package com.idea.relax.crypto.config;

import com.idea.relax.crypto.core.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;

/**
 * @author: 沉香
 * @date: 2023/2/27
 * @description:
 */
@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration(
	proxyBeanMethods = false
)
@EnableConfigurationProperties(RelaxCryptoProperties.class)
public class CryptoAutoConfiguration {

	public CryptoAutoConfiguration() {
		erasureJCE();
	}

	@Bean
	@ConditionalOnMissingBean
	public ICryptographer aesCryptographer(){
		return new AesCryptographer();
	}

	@Bean
	@ConditionalOnMissingBean
	public ICryptographer desCryptographer(){
		return new DesCryptographer();
	}

	@Bean
	@ConditionalOnMissingBean
	public ICryptographerRegister cryptographerRegister(List<ICryptographer> cryptographers) {
		ICryptographerRegister cryptographerRegister = new CryptographerRegister();
		cryptographerRegister.register(cryptographers);
		return cryptographerRegister;
	}

	private static void erasureJCE() {
		Field field;
		try {
			field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted");
			field.setAccessible(true);
			Field modifiersField = Field.class.getDeclaredField("modifiers");
			modifiersField.setAccessible(true);
			modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
			field.set(null, false);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}
